//
//  HYPCImportViewModel.m
//  XPlayer
//
//  Created by liguoqing on 2023/9/14.
//

#import "HYPCImportViewModel.h"
#import "HYHomeFolderModel.h"
#import "HYHomeFileItemViewModel.h"
#import <HYVideoPlayer/HYVideoPlayerConfig.h>
#import <HYVideoPlayer/HYVideoModel.h>
#import "HYPreviewHistoryModel.h"

@interface HYPCImportViewModel ()

@property (nonatomic, strong) NSMutableArray *dataSource;

@property (nonatomic, strong) NSMutableArray *videoSource;

@property (nonatomic, strong) NSMutableArray *audioSource;

@property (nonatomic, strong) NSMutableArray *fileSource;

@property (nonatomic, strong) NSMutableArray *picSource;

@property (nonatomic, strong) NSMutableArray *otherSource;

@property (nonatomic, strong)  dispatch_source_t source;
/// 视频源
@property (nonatomic, strong) NSMutableArray *playVideos;
/// 音频源
@property (nonatomic, strong) NSMutableArray *playAudios;
/// 相册源
@property (nonatomic, strong) NSMutableArray *imageSource;
/// 文件夹资源
@property (nonatomic, strong) NSMutableArray *folderSoucre;
/// 是否开启监听
@property (nonatomic, assign) BOOL isOpenMonitor;
/// 获取文件导入文件夹信息
@property (nonatomic, strong) HYHomeFolderModel *folderModel;

@end

@implementation HYPCImportViewModel

- (void)fetchData
{
    NSArray *files = [kFileManager contentsOfDirectoryAtPath:self.folderPath error:nil];
    if(!files.count){
        [self.updatedContentSignal sendNext:@[]];
        return;
    }
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self.dataSource removeAllObjects];
        [self.videoSource removeAllObjects];
        [self.audioSource removeAllObjects];
        [self.fileSource removeAllObjects];
        [self.picSource removeAllObjects];
        [self.otherSource removeAllObjects];
        [self.playAudios removeAllObjects];
        [self.playVideos removeAllObjects];
        [self.folderSoucre removeAllObjects];
        // 判断是否是文件夹
        BOOL isDir = NO;
        for (NSString *fileName in files) {
            NSString *path = [self.folderPath stringByAppendingPathComponent:fileName];
            [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:(&isDir)];
            HYHomeFileItemViewModel *itemViewModel = [[HYHomeFileItemViewModel alloc]init];
            itemViewModel.setSubject = self.setSubject;
            itemViewModel.fileName = fileName;
            itemViewModel.filePath = path;
            itemViewModel.folderPath = [self.folderPath substringFromIndex:[HYFileManager documentDirectory].length];
            NSDate *createDate = [HYFileManager getSingalFileCreateDateWithFilePath:path];
            NSArray *fileArray = [fileName componentsSeparatedByString:@"."];
            itemViewModel.fileSuffixName = [fileArray count]>1?fileArray.lastObject:@"";
            if ([fileName containsString:@"epubExtraction"]) {
                continue;
            }
            if(isDir){
                itemViewModel.fileType = HYHomeFileType_Folder;
                [self.folderSoucre addObject:itemViewModel];
                itemViewModel.fileSize = [HYFileManager getCacheSizeWithFolderPath:path];
            }else{
                itemViewModel.fileType = [[HYFileManager shareManager] fetchFileTypeWithFileName:fileName];
                NSString *fileSize = [CommUtls getSize:@([HYFileManager getSingleFileSizeWithFilePath:path])];
                if(itemViewModel.fileType == HYHomeFileType_Video || itemViewModel.fileType == HYHomeFileType_Audio){
                    HYVideoModel *videoModel = [[HYVideoModel alloc]init];
                    videoModel.videoTitle = itemViewModel.fileName;
                    videoModel.videoUrl = itemViewModel.filePath;
                    NSString *videoDuration = [CommUtls fetchVideoDurationWithUrl:itemViewModel.filePath];
                    videoModel.videoDuration = videoDuration;
                    itemViewModel.videoDuration = videoDuration;
                    videoModel.createDate = [CommUtls encodeTimeYearMonthDay:createDate];
                    videoModel.importDate = [CommUtls encodeTimeYearMonthDay:createDate];;
                    videoModel.videoSize = fileSize;
                    videoModel.isPrivate = itemViewModel.isLock;
                    if(itemViewModel.fileType == HYHomeFileType_Audio){
                        videoModel.isAudio = YES;
                        [self.playAudios addObject:videoModel];
                        [self.audioSource addObject:itemViewModel];
                    }else{
                        videoModel.videoImage = [CommUtls fetchVideoCoverImageWithUrl:itemViewModel.filePath atTime:1.0];
                        [self.playVideos addObject:videoModel];
                        [self.videoSource addObject:itemViewModel];
                    }
                }else if (itemViewModel.fileType == HYHomeFileType_Pic){
                    [self.imageSource addObject:path];
                    [self.picSource addObject:itemViewModel];
                }else if (itemViewModel.fileType == HYHomeFileType_File || itemViewModel.fileType == HYHomeFileType_Zip){
                    [self.fileSource addObject:itemViewModel];
                }else{
                    [self.otherSource addObject:itemViewModel];
                }
                itemViewModel.fileSize = [HYFileManager getSingleFileSizeWithFilePath:path];
            }
            itemViewModel.createDate = [CommUtls encodeTimeYearMonthDay:createDate];
            itemViewModel.importDate = [CommUtls encodeTimeYearMonthDay:createDate];
            itemViewModel.folderIdentification = self.folderModel.folderIdentification;
        }
        if(self.folderSoucre.count){
            [self.dataSource addObjectsFromArray:[self.folderSoucre copy]];
        }
        if(self.videoSource.count){
            [self.dataSource addObjectsFromArray:[self.videoSource copy]];
        }
        if(self.audioSource.count){
            [self.dataSource addObjectsFromArray:[self.audioSource copy]];
        }
        if(self.fileSource.count){
            [self.dataSource addObjectsFromArray:[self.fileSource copy]];
        }
        if(self.picSource.count){
            [self.dataSource addObjectsFromArray:[self.picSource copy]];
        }
        if(self.otherSource.count){
            [self.dataSource addObjectsFromArray:[self.otherSource copy]];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.updatedContentSignal sendNext:self.dataSource];
        });
    });
}

#pragma mark - UITableViewDelegate
- (NSInteger)numberOfRowsIsHeader:(BOOL)isHeader fileType:(HYHomeFileType)fileType
{
    if(fileType == HYHomeFileType_All){
        return self.dataSource.count;
    }else if (fileType == HYHomeFileType_Video){
        return self.videoSource.count;
    }else if (fileType == HYHomeFileType_Audio){
        return self.audioSource.count;
    }else if (fileType == HYHomeFileType_File){
        return self.fileSource.count;
    }else if (fileType == HYHomeFileType_Pic){
        return self.picSource.count;
    }
    return self.otherSource.count;
}

- (id)cellForRowAtIndexPath:(NSIndexPath *)indexPath isHeader:(BOOL)isHeader fileType:(HYHomeFileType)fileType
{
    HYHomeFileItemViewModel *itemViewModel;
    if(fileType == HYHomeFileType_All){
        itemViewModel = self.dataSource[indexPath.row];
    }else if (fileType == HYHomeFileType_Video){
        itemViewModel = self.videoSource[indexPath.row];
    }else if (fileType == HYHomeFileType_Audio){
        itemViewModel = self.audioSource[indexPath.row];
    }else if (fileType == HYHomeFileType_File){
        itemViewModel = self.fileSource[indexPath.row];
    }else if (fileType == HYHomeFileType_Pic){
        itemViewModel = self.picSource[indexPath.row];
    }else{
        itemViewModel = self.otherSource[indexPath.row];
    }
    itemViewModel.isHiddenSet = self.isSelectFile;
    return itemViewModel;
}

- (HYHomeFileType)fetchFileType:(NSIndexPath *)indexPath fileType:(HYHomeFileType)fileType
{
    HYHomeFileItemViewModel *itemViewModel = [self cellForRowAtIndexPath:indexPath isHeader:NO fileType:fileType];
    return itemViewModel.fileType;
}

#pragma mark - 文件夹重命名
- (void)modifyFileNameWithFileViewModel:(HYHomeFileItemViewModel *)fileVM
{
    NSInteger index = [self.dataSource indexOfObject:fileVM];
    NSInteger subIndex = 0;
    BOOL result =  [fileVM modifyFileNameToSandbox];
    if(result){
        if(fileVM.fileType == HYHomeFileType_Video){
            subIndex = [self.videoSource indexOfObject:fileVM];
        }else if (fileVM.fileType == HYHomeFileType_Audio){
            subIndex = [self.audioSource indexOfObject:fileVM];
        }else if (fileVM.fileType == HYHomeFileType_File || fileVM.fileType == HYHomeFileType_Zip){
            subIndex = [self.fileSource indexOfObject:fileVM];
        }else if (fileVM.fileType == HYHomeFileType_Pic){
            subIndex = [self.picSource indexOfObject:fileVM];
        }else if (fileVM.fileType == HYHomeFileType_Other){
            subIndex = [self.otherSource indexOfObject:fileVM];
        }
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
        NSIndexPath *subIndexPath = [NSIndexPath indexPathForRow:subIndex inSection:0];
        [self.reloadSubject sendNext:RACTuplePack(@(fileVM.fileType),indexPath,subIndexPath)];
    }
}

- (void)deleteRowsAtIndexPaths:(NSIndexPath *)indexPath fileType:(HYHomeFileType)fileType
{
    HYHomeFileItemViewModel *itemViewModel = self.dataSource[indexPath.row];
    NSString *filePath = itemViewModel.filePath;
    BOOL isSuccess = [kFileManager removeItemAtPath:filePath error:nil];
    if(isSuccess){
        if(itemViewModel.fileType == HYHomeFileType_Video){
            [self.videoSource removeObject:itemViewModel];
            HYVideoModel *videoModel = [self fetchCurrentVideoWithItemViewModel:itemViewModel];
            [self.playVideos removeObject:videoModel];
        }else if (itemViewModel.fileType == HYHomeFileType_Audio){
            [self.audioSource removeObject:itemViewModel];
            HYVideoModel *audioModel = [self fetchCurrentAudioWithItemViewModel:itemViewModel];
            [self.playAudios removeObject:audioModel];
        }else if (itemViewModel.fileType == HYHomeFileType_File || itemViewModel.fileType == HYHomeFileType_Zip){
            [self.fileSource removeObject:itemViewModel];
        }else if (itemViewModel.fileType == HYHomeFileType_Pic){
            [self.picSource removeObject:itemViewModel];
        }else if (itemViewModel.fileType == HYHomeFileType_Other){
            [self.otherSource removeObject:itemViewModel];
        }
        [self.dataSource removeObject:itemViewModel];
        [self.updatedContentSignal sendNext:self.dataSource];
    }
}

- (void)didSelectRowAtIndexPath:(NSIndexPath *)indexPath isHeader:(BOOL)isHeader fileType:(HYHomeFileType)fileType
{
    HYHomeFileItemViewModel *itemViewModel = [self cellForRowAtIndexPath:indexPath isHeader:NO fileType:fileType];
    [self.showFileSubject sendNext:itemViewModel];
}

- (HYVideoViewModel *)fetchPlayVideoConfigWithItemViewModel:(HYHomeFileItemViewModel *)itemViewModel
{
    HYVideoModel *currentModel;
    if(itemViewModel.fileType == HYHomeFileType_Video){
        currentModel = [self fetchCurrentVideoWithItemViewModel:itemViewModel];
    }else{
        currentModel = [self fetchCurrentAudioWithItemViewModel:itemViewModel];
    }
    if(currentModel){
        currentModel.isSelect = YES;
        HYVideoPlayerConfig *config = [[HYVideoPlayerConfig alloc]init];
        config.isBasePlayer = YES;
        config.currentVideoModel = currentModel;
        config.videoSoucres = itemViewModel.fileType == HYHomeFileType_Video?self.playVideos:self.playAudios;
        config.isAudioMode = itemViewModel.fileType == HYHomeFileType_Video?NO:YES;
        HYVideoViewModel *viewModel = [[HYVideoViewModel alloc]initWithFolderIdentification:self.folderModel.folderIdentification
                                                                                  isPrivate:self.folderModel.isLock
                                                                                videoConfig:config];
        viewModel.folderPath = itemViewModel.folderPath;
        return viewModel;
    }
    return nil;
}

#pragma mark - 获取点击视频的索引
- (HYVideoModel *)fetchCurrentVideoWithItemViewModel:(HYHomeFileItemViewModel *)itemViewModel
{
    __block HYVideoModel *playModel;
    [self.playVideos enumerateObjectsUsingBlock:^(HYVideoModel *videoModel, NSUInteger idx, BOOL * _Nonnull stop) {
        if([videoModel.videoUrl isEqualToString:itemViewModel.filePath]){
            playModel = videoModel;
            *stop = YES;
        }
    }];
    return playModel;
}

- (HYVideoModel *)fetchCurrentAudioWithItemViewModel:(HYHomeFileItemViewModel *)itemViewModel
{
    __block HYVideoModel *playModel;
    [self.playAudios enumerateObjectsUsingBlock:^(HYVideoModel *videoModel, NSUInteger idx, BOOL * _Nonnull stop) {
        if([videoModel.videoUrl isEqualToString:itemViewModel.filePath]){
            playModel = videoModel;
            *stop = YES;
        }
    }];
    return playModel;
}

#pragma mark - 删除文件
- (void)deleteFilWithFileViewModel:(HYHomeFileItemViewModel *)fileVM
{
    BOOL result = [fileVM removeDocumentFile];
    if(result){
        [self removeFileFromListSourceWithFileModel:fileVM];
    }
}

#pragma mark - 数据源中移除文件
- (void)removeFileFromListSourceWithFileModel:(HYHomeFileItemViewModel *)fileVM
{
    if(fileVM.fileType == HYHomeFileType_Folder){
        [self.folderSoucre removeObject:fileVM];
    }else if(fileVM.fileType == HYHomeFileType_Video){
        [self.videoSource removeObject:fileVM];
        HYVideoModel *model = [self fetchCurrentVideoWithFileModel:fileVM];
        [self.playVideos removeObject:model];
    }else if (fileVM.fileType == HYHomeFileType_Audio){
        [self.audioSource removeObject:fileVM];
        HYVideoModel *model = [self fetchCurrentVideoWithFileModel:fileVM];
        [self.playAudios removeObject:model];
    }else if(fileVM.fileType == HYHomeFileType_File || fileVM.fileType == HYHomeFileType_Zip){
        [self.fileSource removeObject:fileVM];
    }else if (fileVM.fileType == HYHomeFileType_Pic){
        [self.picSource removeAllObjects];
    }else if (fileVM.fileType == HYHomeFileType_Other){
        [self.otherSource removeAllObjects];
    }
    [self.dataSource removeObject:fileVM];
    if(!self.isOpenMonitor){
        [self.updatedContentSignal sendNext:self.dataSource];
    }
}


#pragma mark - 监听文件上传Document文件夹的变化
- (void)startMonitorFile
{
    NSURL *directoryURL = [NSURL URLWithString:self.folderPath]; //添加需要监听的目录
    int const fd = open([[directoryURL path] fileSystemRepresentation], O_EVTONLY);
    if (fd < 0) {
        self.isOpenMonitor = NO;
        CLog(@"Unable to open the path = %@", [directoryURL path]);
        return;
    }
    dispatch_source_t source =
    dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd,
                           DISPATCH_VNODE_WRITE,
                           DISPATCH_TARGET_QUEUE_DEFAULT);
    dispatch_source_set_event_handler(source, ^() {
        unsigned long const type = dispatch_source_get_data(source);
        switch (type) {
            case DISPATCH_VNODE_WRITE:{
                //延时1s刷新保证能获取文件信息
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [self fetchData];
                });
            }
                break;

            default:
                break;
        }
    });
    dispatch_source_set_cancel_handler(source, ^{
        close(fd);
    });
    self.source = source;
    dispatch_resume(self.source);
    self.isOpenMonitor = YES;
}

#pragma mark - 停止监听
- (void)stopMonitorFile
{
    if(self.source){
        dispatch_cancel(self.source);
        self.isOpenMonitor = NO;
    }
}

#pragma mark - 新建文件夹
- (void)createFolderWithFolderName:(NSString *)folderName completeBlock:(HYBIdBlock)completeBlock
{
    NSString *folderPath = [HYFileManager createFolderPathWithFolderName:folderName filePath:self.folderPath];
    if(folderPath.length){
        if(!self.isOpenMonitor || self.isFileMove){
            HYHomeFileItemViewModel *itemViewModel = [[HYHomeFileItemViewModel alloc]init];
            itemViewModel.setSubject = self.setSubject;
            itemViewModel.fileName = folderName;
            itemViewModel.filePath = folderPath;
            itemViewModel.fileType = HYHomeFileType_Folder;
            itemViewModel.folderPath = [self.folderPath substringFromIndex:[HYFileManager documentDirectory].length];
            itemViewModel.folderIdentification = self.folderModel.folderIdentification;
            itemViewModel.createDate = [CommUtls encodeTimeYearMonthDay:[NSDate date]];
            [self.folderSoucre addObject:itemViewModel];
            [self.dataSource insertObject:itemViewModel atIndex:0];
            [self.updatedContentSignal sendNext:self.dataSource];
            if(completeBlock){
                completeBlock(itemViewModel);
            }
        }
    }else{
        [HYHub showMessage:NSLocalizedString(@"文件夹已存在", nil)];
    }
}

#pragma mark - 文件夹移动
- (NSArray *)fetchCurrentListFolder:(HYHomeFileItemViewModel *)fileVM
{
    __block NSMutableArray *tempFolders = [NSMutableArray array];
    if(self.parentPath.length){
        HYHomeFileItemViewModel *itemViewModel = [[HYHomeFileItemViewModel alloc]init];
        itemViewModel.fileName = NSLocalizedString(@"上一级", nil);
        itemViewModel.filePath = self.parentPath;
        itemViewModel.fileType = HYHomeFileType_Folder;
        [tempFolders addObject:itemViewModel];
    }
    if(fileVM.fileType != HYHomeFileType_Folder){
        [tempFolders addObjectsFromArray:[self.folderSoucre copy]];
        return [tempFolders copy];
    }
    [self.folderSoucre enumerateObjectsUsingBlock:^(HYHomeFileItemViewModel *folderModel, NSUInteger idx, BOOL * _Nonnull stop) {
        if(fileVM != folderModel){
            [tempFolders addObject:folderModel];
        }
    }];
    return [tempFolders copy];
}

- (void)moveToFolderWithCurrentFile:(HYHomeFileItemViewModel *)currentFileModel
                      completeBlock:(dispatch_block_t)completeBlock
{
    if(!self.selectFolderModel){
        [HYHub showMessage:NSLocalizedString(@"请选择移动至的‘文件夹’", nil)];
        return;
    }
    BOOL isSuccess = [HYFileManager moveFileWithFromPath:currentFileModel.filePath toPath:self.selectFolderModel.filePath];
    if(isSuccess){
        [currentFileModel moveDocumentFileToFolderPath:[self.selectFolderModel.filePath substringFromIndex:[HYFileManager documentDirectory].length]];
        [self removeFileFromListSourceWithFileModel:currentFileModel];
        if([self.selectFolderModel.fileName isEqualToString:NSLocalizedString(@"上一级", nil)]){
            [self.refreshSubject sendNext:nil];
        }
        completeBlock();
    }else{
        [HYHub showMessage:NSLocalizedString(@"该文件已存在",nil)];
    }
}

- (RACTuple *)showImageWithFileVM:(HYHomeFileItemViewModel *)fileVM
{
    __block NSInteger index;
    [self.imageSource enumerateObjectsUsingBlock:^(NSString *imagePath, NSUInteger idx, BOOL * _Nonnull stop) {
        if([imagePath isEqualToString:fileVM.filePath]){
            index = idx;
            *stop = YES;
        }
    }];
    return RACTuplePack(self.imageSource,@(index));
}

#pragma mark - loadLazy

- (NSMutableArray *)dataSource
{
    if(!_dataSource){
        _dataSource = [NSMutableArray array];
    }
    return _dataSource;
}

- (NSMutableArray *)videoSource
{
    if(!_videoSource){
        _videoSource = [NSMutableArray array];
    }
    return _videoSource;
}

- (NSMutableArray *)audioSource
{
    if(!_audioSource){
        _audioSource = [NSMutableArray array];
    }
    return _audioSource;
}

- (NSMutableArray *)picSource
{
    if(!_picSource){
        _picSource = [NSMutableArray array];
    }
    return _picSource;
}

- (NSMutableArray *)fileSource
{
    if(!_fileSource){
        _fileSource = [NSMutableArray array];
    }
    return _fileSource;
}

- (NSMutableArray *)otherSource
{
    if(!_otherSource){
        _otherSource = [NSMutableArray array];
    }
    return _otherSource;
}

- (NSMutableArray *)playVideos
{
    if(!_playVideos){
        _playVideos = [NSMutableArray array];
    }
    return _playVideos;
}

- (NSMutableArray *)playAudios
{
    if(!_playAudios){
        _playAudios = [NSMutableArray array];
    }
    return _playAudios;
}

- (NSMutableArray *)imageSource
{
    if(!_imageSource){
        _imageSource = [NSMutableArray array];
    }
    return _imageSource;
}

- (NSMutableArray *)folderSoucre
{
    if(!_folderSoucre){
        _folderSoucre = [NSMutableArray array];
    }
    return _folderSoucre;
}

- (HYHomeFolderModel *)folderModel
{
    if(!_folderModel){
        NSString *sql = [NSString stringWithFormat:@"select * from FOLDERLIST where folderType = '%ld'",HYHomeFileType_Document];
        _folderModel = [HYHomeFolderModel searchWithSQL:sql].firstObject;
    }
    return _folderModel;
}

@end
